#include <devFileOpt.h>
#include <genrand.h>

#if DEVICE_PLATFORM_CONFIGURE == DEVICE_PLATFORM_LINUX
int stringPcFree(struct stringPc *str)
{
    if(str->sdata)
    {
        free(str->sdata);
        str->sdata = NULL;
    }
    str->ssize = 0;
    return 0;
}
int stringPcResize(struct stringPc *str, uint32_t rsize)
{
    stringPcFree(str);
    str->sdata = (uint8_t *)malloc(rsize);
    if(!str->sdata)
    {
        logerror("");
        return 0;
    }
    str->ssize = rsize;
    return rsize;
}
int stringPcCopy(struct stringPc *str, const void *fdata, uint32_t offset, uint32_t dsize)
{
    if(str->ssize < offset + dsize)
    {
        logerror("%s:%d<%d", str->ssize, offset + dsize);
        return -1;
    }
    memcpy(&str->sdata[offset], fdata, dsize);
    return dsize;
}
int stringPcRead(struct stringPc *str, void *fdata, uint32_t offset, uint32_t dsize)
{
    if(str->ssize < offset + dsize)
    {
        logerror("%s:%d<%d", str->ssize, offset + dsize);
        return -1;
    }
    memcpy(fdata, &str->sdata[offset], dsize);
    return dsize;
}

int readLocalFile(const char *filepath, char *readbuff, int readsize)
{
    FILE *tmpfile;
    int tmpsize;
    if (!filepath)
    {
        logerror("");
        return -1;
    }
    if (!(readbuff && readsize > 0))
    {
        logerror("");
        return -1;
    }
    tmpfile = fopen(filepath, "r");
    if (!tmpfile)
    {
        logerror("open error %s", filepath);
        return -1;
    }
    tmpsize = fread(readbuff, 1, readsize, tmpfile);
    fclose(tmpfile);
    return tmpsize;
}
int writeLocalFile(const char *filepath, const char *writebuff, int writesize)
{
    FILE *tmpfile;
    int tmpsize;
    if (!filepath)
    {
        logerror("");
        return -1;
    }
    if (!(writebuff && writesize > 0))
    {
        logerror("");
        return -1;
    }
    tmpfile = fopen(filepath, "w+");
    if (!tmpfile)
    {
        logerror("open error %s", filepath);
        return -1;
    }
    tmpsize = fwrite(writebuff, 1, writesize, tmpfile);
    fclose(tmpfile);
    return tmpsize;
}
#endif

int devFileWriteBegin(struct devFileOptStruct *devfile, const uint8_t *fname, uint32_t fsize)
{
    logdebug("file opt begin:%s:%d", fname, fsize);
    if(strcmp(fname, DEV_UPGRADE_NAME) == 0)
    {
        if(fsize > DEV_UPGRADE_MAX_SIZE)
        {
            return -1;
        }
    }
    else
    {
        return -1;
    }
#if DEVICE_PLATFORM_CONFIGURE == DEVICE_PLATFORM_LINUX
    memcpy(devfile->fname, fname, sizeof(devfile->fname));
    devfile->fsize = fsize;
    stringPcResize(&devfile->str, devfile->fsize);
#else
#endif
    return 0;
}
int devFileWriteData(struct devFileOptStruct *devfile, uint32_t offset, const uint8_t *fdata, uint32_t dsize)
{
#if DEVICE_PLATFORM_CONFIGURE == DEVICE_PLATFORM_LINUX
    return stringPcCopy(&devfile->str, fdata, offset, dsize);
#else
#endif
}
int devFileWriteEnd(struct devFileOptStruct *devfile, uint32_t dcrc)
{
#if DEVICE_PLATFORM_CONFIGURE == DEVICE_PLATFORM_LINUX
    uint32_t i;
    devfile->fcrc = 0;
    for(i = 0; i < devfile->str.ssize; i++)
    {
        devfile->fcrc += devfile->str.sdata[i];
    }
    if(dcrc == devfile->fcrc)
    {
        return 0;
    }
    return -1;
#else
#endif
}
int devFileReadData(struct devFileOptStruct *devfile, uint32_t offset, uint8_t *fdata, uint32_t dsize)
{
#if DEVICE_PLATFORM_CONFIGURE == DEVICE_PLATFORM_LINUX
    return stringPcRead(&devfile->str, fdata, offset, dsize);
#else
#endif
}
struct devFileOptStruct *foptInst()
{
    static struct devFileOptStruct MCU_XDATA_TYPE dfopt = {{0}, 0, 0};
    return &dfopt;
}
